/*
 * @FilePath: /app/plc/PLCClient.cpp
 * @Author: Wilson
 * @Descripttion: 
 * @Date: 2021-08-19 21:37:37
 * @LastEditors: Wilson
 * @LastEditTime: 2021-08-19 23:40:11
 */
#include "PLCClient.h"
#include <thread>
#include <glog/logging.h>

#include "common/global.h"

namespace plc
{
    bool PLCClient::Init(std::string ip, std::list<int> readDBList)
    {
        _client = std::make_shared<TS7Client>();
        int res = _client->ConnectTo(ip.c_str(), 0, 1);
        if (res != 0)
        {
            LOG(WARNING) << "连接失败: " << ip << ", " << CliErrorText(res);
            return false;
        }
        LOG(INFO) << "连接成功: " << ip;

        std::thread([this, readDBList]() {
            LOG(INFO) << "plc read thread start";
            while (!Global::_isExit)
            {
                usleep(500 * 1000);
                for (auto key : readDBList)
                {
                    ReadDB(key, 0);
                }
            }
            LOG(INFO) << "plc read thread end";
        }).detach();

        return true;
    }

    void PLCClient::Release()
    {
        if (_client != NULL)
        {
            LOG(INFO) << "断开连接";
            _client->Disconnect();
        }
    }

    bool PLCClient::sendDB(int db)
    {
        if (_client == NULL)
        {
            LOG(WARNING) << "client is nullptr";
            return false;
        }
        if (_dbWriteBuffer.find(db) == _dbWriteBuffer.end())
        {
            LOG(WARNING) << "no such db: " << db;
            return false;
        }
        int res = _client->DBWrite(db, 0, WRITE_BUFFER_SIZE, _dbWriteBuffer[db]);
        if (res != 0)
        {
            LOG(WARNING) << "DB写失败: " << db << ", " << CliErrorText(res);
            return false;
        }
        LOG(INFO) << "DB写成功";
        return true;
    }

    bool PLCClient::WriteDB(int db, int index, int value)
    {
        if ((index < 0) || (index >= WRITE_BUFFER_SIZE))
        {
            LOG(WARNING) << "WriteDB failed: index is error - " << index;
            return false;
        }

        //DB6 X0.0 设置为1，byte buffer[8] ={1,0,0,0,0,0,0,0};
        //DB6 X0.1 设置为1，byte buffer[8] ={2,0,0,0,0,0,0,0};
        //DB6 X0.2 设置为1，byte buffer[8] ={4,0,0,0,0,0,0,0};
        _dbWriteBuffer[db][index] = value;
        return sendDB(db);
    }

    bool PLCClient::ReadDB(int db, int index)
    {
        if ((index < 0) || (index >= READ_BUFFER_SIZE))
        {
            LOG(WARNING) << "ReadDB failed: index is error - " << index;
            return false;
        }
        byte buffer[READ_BUFFER_SIZE] = {0};
        int res = _client->DBRead(db, 0, READ_BUFFER_SIZE, buffer);
        if (res != 0)
        {
            LOG(WARNING) << "DB读失败: " << db << ", " << CliErrorText(res);
            return false;
        }

        std::stringstream str;
        str << "db"<<db<<", data: ";
        for (int i = 0; i < READ_BUFFER_SIZE; i++)
        {
            _dbReadBuffer[db][i] = buffer[i];
            str << (int)_dbReadBuffer[db][i] << " ";
        }
        LOG(INFO) << str.str();

        return true;
    }
}
